#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <termios.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>

#include "click.h"
#include "color.h"
#include "carton.h"
#include "homepage.h"
#include "leaderboard.h"
#include "configuration.h"

static struct itimerval oldtv;
static struct itimerval itv;
static uint8_t g_time = 0;

static void carton_click_1(void);
static void carton_click_2(void);
static void show_click_help(void);
static void signal_handler(int sign_no);
static void timer_init(void);

/**
 * @brief   显示疯狂点击游戏分支菜单
 * @param   void
 * @return  void
 */ 
void show_click_menu(void)
{
    printf(L_RED);
    printf(BLINK "\t==== Welcome to CLICK GAME!! ====\n\n\t" NONE);

    printf(YELLOW);
    printf(""
        "========== CLICK GAME ==========\n\t"
        "================================\n\t"
        "*                              *\n\t"
        "*       1. Game Start          *\n\t"
        "*                              *\n\t"
        "*       2.    Help             *\n\t"
        "*                              *\n\t"
        "*       3. Last Menu           *\n\t"
        "*                              *\n\t"
        "================================\n\t"
        "*                              *\n\t"
        "*       PLEASE SELECT 1~3:     *\n\t"
        "*                              *\n\t"
        "================================\n");
    printf(NONE);
}

/**
 * @brief   疯狂点击分支菜单输入判断, 按下1开始游戏,
 *          按下2查看帮助, 按下3返回主菜单.
 * @param   void
 * @return  void
 */
void choice_click_menu(void)
{
       char input_menu[32];

    while (1) {
        set_buffered_input(false);
        input_menu[0] = getchar();
        set_buffered_input(true);
        switch (input_menu[0]) {
            case START:
                system("clear");
                game_click_start();
                break;

            case HELP:
                system("clear");
                show_click_help();
                break;

            case COME_BACK:
                system("clear");
                show_main_menu();
                choice_main_menu();
                break;

            default :
                system("clear");
                show_click_menu();
                printf(L_RED "\n\tERROR INPUT!\r\n" NONE);
                choice_click_menu();
                continue;
        }
    }
}

/**
 * @brief   疯狂点击帮助显示
 * @param   void
 * @return  void
 */
void show_click_help(void)
{
    show_click_menu();

    printf(L_GREEN);
    printf("\n"
        "1. Game rules: You can enter the key 'SPACE'"
            " to add click number, or enter the key 'q'"
            " to quit this game within TEN seconds!\r\n"
        "2. Game suggestion: Crazy to click it!");
    printf(NONE);

    choice_click_menu();
}

/**
 * @brief   疯狂点击开始游戏初始化
 * @param   void
 * @return  void
 */
void game_click_start(void)
{
    char click_input[32];
    uint32_t click_total = 0;

    carton_buddha();
    printf(YELLOW "\nEnter SPACE to start!\n" NONE);

    set_buffered_input(false);
    click_input[0] = getchar();
    set_buffered_input(true);
    if (click_input[0] == KEY_SPACE) {

        g_time = 0;
        timer_init();
    } else {

        system("clear");
        printf(L_RED "\tERROR INPUT!\n\n" NONE);
        game_click_start();
    }

    system("clear");
    carton_click_1();

    while (1) {

        printf(YELLOW "\n");
        printf("Score:%d\n", click_total);
        printf("\n\tEnd aften TEN seconds:%d\n", g_time);
        printf("\n\tINPUT:'q' -QUIT; 'SPACE' -CLICK ONCE\n");
        printf(NONE);
        set_buffered_input(false);
        click_input[0] = getchar();
        set_buffered_input(true);

        switch (click_input[0]) {

            case KEY_SPACE:
                click_total++;
                printf(YELLOW "\n");
                printf("Score:%d\n", click_total);
                printf("\n\tEnd aften TEN seconds:%d\n", g_time);
                printf("\n\tINPUT:'q' -QUIT; 'SPACE' -CLICK ONCE\n");
                printf(NONE);

                if (click_total % 2 == 0)
                    carton_click_1();
                else
                    carton_click_2();    
                break;

            case KEY_QUIT:
                printf("\n\tEnd aften TEN seconds:%d s\n", g_time);
                printf(L_RED "Whether to QUIT(y/n):\r\n" NONE);
                set_buffered_input(false);
                click_input[0] = getchar();
                set_buffered_input(true);

                if (click_input[0] == 'y') {
                    system("clear");
                    show_click_menu();
                    choice_click_menu();
                } else {
                    system("clear");
                    printf(L_GREEN "Return to this game!\r\n" NONE);
                    continue;
                }
                break;

            default:
                system("clear");
                break;
        }

        if (g_time > 10) {

            if (click_total >= 100)
                carton_good();
            else
                carton_stupid();
            
            printf(L_RED "\n\tYou Score is %d\n" NONE, click_total);
            click_score_get(click_total);
            click_board_put();
            
            printf("\nAnything key to menu(SPACE to quit):\n");
            set_buffered_input(false);
            click_input[0] = getchar();
            set_buffered_input(true);

            if (click_input[0] != EOF && click_input[0] != KEY_SPACE) {
                system("clear");
                show_click_menu();
                choice_click_menu();
            } 
            else 
                exit(EXIT_SUCCESS);
        }
    }
}

/**
 * @brief   疯狂点击定时计数器:函数型指针定义
 * @param   int sign_no
 * @return  void
 */
static void signal_handler(int sign_no)
{
    if (sign_no == SIGALRM)
        g_time++;
}

/**
 * @brief   疯狂点击定时计数器初始化
 * @param   void
 * @return  void
 */
static void timer_init(void)
{
    signal(SIGALRM, signal_handler);

    itv.it_interval.tv_sec = 1;
    itv.it_interval.tv_usec = 0;
    itv.it_value.tv_sec = 1;
    itv.it_value.tv_usec = 0;
    setitimer(ITIMER_REAL, &itv, &oldtv);
}

/**
 * @brief   疯狂点击游戏动画效果:carton_click_1(), carton_click_2()
 * @param   void
 * @return  void
 */
void carton_click_1(void)
{
    system("clear");
    printf( YELLOW
            "\n\n"
            "\t  ______ \r\n"
            "\t|        |\r\n"
            "\t|__Come__|\r\n"
            NONE);
}

void carton_click_2(void)
{
    system("clear");
    printf( YELLOW
            "\n\n"
            "\t`        `\r\n"
            "\t `______`\r\n"
            "\t/__Hum!__\\\r\n"
            NONE);
}
